<?php
namespace App\handlers;

//use App\Message;
use App\Console\Commands\Swoole;
use Illuminate\Support\Facades\Redis;
use App\Services\BaseService;

class SwooleHandler
{
    public function __construct()//Message $message
    {
//        $this->message = $message;

    }



    public function onOpen($ws, $request) {

    }



    //监听WebSocket消息事件
    /*
     *  $frame 对象(非数组)格式
     * {
          fd=>1
          finish=>true
          opcode=>1
          data=>"{"message":"asd","user_id":6,"room_id":1,"type":"message"}"
        }

     * */
    public function onMessage($ws, $frame) {
        //redis 操作demo
        //    Redis::hmset('fangjian100',['a'=>12,'b'=>45]);
        //    Redis::hmset('fangjian101',['a'=>112,'b'=>6445]);
        //    Redis::hmset('fangjian102',['a'=>1122,'b'=>43215]);//设置值
        //    Redis::del('fangjian100'); //删除值
        //    Redis::hgetall('fangjian102')  //获取值,不存在时，返回一个空数组: []
        //    var_dump(Redis::hset('fangjian102', 'a',145225));
        //    var_dump(Redis::hget('fangjian102', 'a')); 取值【value|false】
        //   Redis::set('key', 1);
        //   Redis::get('key');  //获取key [value]


        $data = json_decode($frame->data, true);

        $room_keyname = $data['room_keyname'];
        $fd_room = BaseService::REDIS_KEY_PREFIX_FD_ROOM;

        switch ($data['type']) {

            case 'connect':
                $user_status = Redis::hget($room_keyname, $data['user_id']);
                //无此用户
                if(false === $user_status){
                    //关闭此用户连接，会触发onClose 事件
//                    $ws->close($frame->fd);
                }else{
                    //重新设置状态
                    Redis::hset($room_keyname, $data['user_id'], $frame );
//                    var_dump($frame,$data['user_id'], $frame->fd);
                    Redis::hset($room_keyname, $data['user_id'], $frame->fd);
                    //保存fd对应的房间编号
                    Redis::hset($fd_room, $frame->fd, $room_keyname .','.$data['user_id']);
                }
                $room_users = Redis::hgetall( $room_keyname );
                $this->sendAll($ws, $room_keyname, $data['user_id'], $room_users ,  'connect');
                break;
            case 'message':
                //广播消息入库
                $this->sendAll($ws, $room_keyname , $data['user_id'], $data['message']);
                break;
            case 'close':
                //将状态改为离线
//                Redis::hset($room_keyname, $data['user_id'], Swoole::OFF_LINE);
//                //删，移除集合key中的一个或多个member元素，不存在的member元素会被忽略 [del_num | false]
//                Redis::srem($room_keyname_fd, $frame->fd);
//                $room_users = Redis::hgetall( $room_keyname );
//                $this->sendAll($ws, $data['room_id'], $data['user_id'], $room_users ,  'leave');
                break;
            case 'order':
                $this->sendAll($ws, $room_keyname , $data['user_id'], $data['message'], 'order');
                break;
        }
    }

    public function onClose($ws, $fd) {
        $fd_room = BaseService::REDIS_KEY_PREFIX_FD_ROOM;
        $tmp = Redis::hget($fd_room, $fd);
        $room_keyname = explode(",",$tmp)[0];
        $user_id = explode(",",$tmp)[1];
        //将状态改为离线
        Redis::hset($room_keyname, $user_id, -1);
        //删除fd对应的房间
        Redis::hdel($fd_room, $fd);
        $room_users = Redis::hgetall( $room_keyname);
        $this->sendAll($ws, $room_keyname, $user_id, $room_users ,  'leave');
    }

    /**
     * @param $ws
     * @param $room_id
     * @param string $user_id
     * @param string $message
     * @param string $type
     * @return bool
     */
    function sendAll($ws, $room_keyname, $user_id = null, $message = null, $type = 'message')
    {

        $message = json_encode([
            'message' => is_string($message) ? nl2br($message) : $message,
            'type' => $type,
            'user_id' => $user_id
        ]);
        //获取房间的所有用户的fd
        $members = Redis::hgetall( $room_keyname );

        foreach ($members as $user_id=>$fd) {
            $ws->push($fd, $message);
        }
    }
}